package com.wosai.teach.thread;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;

import android.app.Activity;
import android.os.Environment;
import android.os.Message;
import android.widget.Toast;

import com.wosai.teach.dao.DownloadInfoDao;
import com.wosai.teach.handler.InstallHandler;
import com.wosai.teach.handler.PBarHandler;
import com.wosai.teach.pojo.DownloadInfo;
import com.wosai.teach.pojo.Experiment;
import com.wosai.teach.pojo.Install;
import com.wosai.teach.utils.AppGlobal;
import com.wosai.teach.utils.C;

public class DownloadRunnable implements Runnable {

	private boolean killFlag = false;
	private Experiment exp;
	private Activity activity;
	private PBarHandler pbHandler;

	private String savePath;// 路径+文件名
	private String fileName; // 文件名
	private DownloadInfo downloadInfo;
	private DownloadFactory factory;

	public DownloadRunnable(Experiment exp, Activity activity,
			PBarHandler pbHandler, DownloadFactory factory) {
		this.exp = exp;
		this.activity = activity;
		this.pbHandler = pbHandler;
		this.factory = factory;
	}

	public void modifyPBarHandler(PBarHandler pbHandler) {
		if (this.pbHandler == null) {
			this.pbHandler = pbHandler;
		} else {
			this.pbHandler.setTv(pbHandler.getTv());
			this.pbHandler.setPbar(pbHandler.getPbar());
		}

	}

	@Override
	public void run() {
		// 初始化文件名
		this.init();
		// 检查是否已下载
		boolean down = this.checkDown();
		if (down) {
			// 初始化下载记录
			this.downloadInit();
			// 下载文件
			this.downLoadFile();
		}
		// 安装
		down = this.checkDown();
		if (!down) {
			this.install();
		} else {
			exp.setStatus(C.TEACH_STATUS_NOT_INSTALL);
			exp.save();
			AppGlobal.instHandler
					.sendEmptyMessage(InstallHandler.INSTALL_RESULT_ERR);
		}
		// 工厂中释放线程
		this.factory.getRunnableSA().remove(exp.getExpId());
	}

	private void init() {
		String tt[] = exp.getApkURL().split("/");
		fileName = tt[tt.length - 1];
		String sdcard = Environment.getExternalStorageDirectory().getPath();
		File tmpFile = new File(sdcard + "/teach_platform");
		if (!tmpFile.exists()) {
			tmpFile.mkdir();
		}
		savePath = sdcard + "/teach_platform/" + fileName;
	}

	/**
	 * 检查是否需要下载安装包
	 * 
	 * @return
	 */
	private boolean checkDown() {
		File file = new File(savePath);
		if (file.exists()) {
			return false;
		}
		return true;
	}

	private void downLoadFile() {
		InputStream is = null;
		HttpURLConnection conn = null;
		try {
			// 作为临时文件
			RandomAccessFile wstFile = new RandomAccessFile(savePath + ".wst",
					"rwd");
			URL url = new URL(exp.getApkURL());
			conn = (HttpURLConnection) url.openConnection();
			conn.setConnectTimeout(5 * 1000);
			conn.setRequestMethod("GET");
			// 获取文件大小
			conn.setRequestProperty(
					"Range",
					"bytes="
							+ (downloadInfo.getStartPos() + downloadInfo
									.getCompeleteSize()) + "-"
							+ downloadInfo.getEndPos());
			wstFile.seek(downloadInfo.getStartPos()
					+ downloadInfo.getCompeleteSize());
			is = conn.getInputStream();
			byte[] buf = new byte[4096];
			// 初始化进度条
			Message msg = new Message();
			msg.what = 0;
			msg.getData().putInt("fileSize", downloadInfo.getEndPos());
			sendMessage(msg);

			if (conn.getResponseCode() >= 400) {
				Toast.makeText(activity, "连接超时", Toast.LENGTH_SHORT).show();
			} else {
				int length = -1;
				int count = 0;
				while ((length = is.read(buf)) > 0) {
					if (killFlag) {
						// 杀死
						wstFile.close();
						is.close();
						conn.disconnect();
						downloadInfo.save();
						return;
					}
					wstFile.write(buf, 0, length);
					downloadInfo.addCompeleteSize(length);
					// 更新进度条
					msg = new Message();
					msg.what = 1;
					msg.getData().putInt("curSize",
							downloadInfo.getCompeleteSize());
					sendMessage(msg);

					if (count++ % 100 == 0) {
						downloadInfo.save();
					}
				}
			}
			// 下载完成
			msg = new Message();
			msg.what = 2;
			sendMessage(msg);
			// 把临时文件改为正式文件
			File file = new File(savePath);
			File ttFile = new File(savePath + ".wst");
			ttFile.renameTo(file);
			wstFile.close();
			is.close();
			conn.disconnect();
			// 删除下载记录
			downloadInfo.delete();
			downloadInfo = null;
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (downloadInfo != null) {
				downloadInfo.save();
			}
		}
	}

	private void sendMessage(Message msg) {
		if (pbHandler != null) {
			if (pbHandler.getFileSize() <= 0) {
				pbHandler.setFileSize(downloadInfo.getEndPos());
			} else {
				pbHandler.sendMessage(msg);
			}
		}
	}

	private void downloadInit() {
		DownloadInfoDao dao = new DownloadInfoDao();
		downloadInfo = dao.getDownloadInfoByExpId(exp.getExpId());
		if (downloadInfo != null && downloadInfo.getEndPos() > 0) {
			return;
		}
		URL url = null;
		int fileSize = 0;
		HttpURLConnection conn = null;
		try {
			url = new URL(exp.getApkURL());
			conn = (HttpURLConnection) url.openConnection();
			conn.setConnectTimeout(5000);
			conn.setRequestMethod("GET");
			fileSize = conn.getContentLength();
			// 未知BUG，加速disconnect，期待okhttp升级
			InputStream is = conn.getInputStream();
			is.close();
			conn.disconnect();
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (ProtocolException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		downloadInfo = new DownloadInfo(0, 0, fileSize - 1, 0, exp.getApkURL(),
				exp.getExpId());
		downloadInfo.save();
	}

	private void install() {
		int requestCode = 0;
		if (exp.getStatus() == C.TEACH_STATUS_INSTALL) {
			// 更新
			requestCode = C.REQUEST_CODE_UPDATE;
		} else {
			// 安装
			requestCode = C.REQUEST_CODE_INSTALL;
		}
		Install inst = new Install();
		inst.setRequestCode(requestCode);
		inst.setSavePath(savePath);
		inst.setExpId(exp.getExpId());
		inst.save();
		exp.setStatus(C.TEACH_STATUS_LOADOVER);
		exp.save();
		AppGlobal.instHandler
				.sendEmptyMessage(InstallHandler.INSTALL_RESULT_OK);
	}

	public void setKillFlag(boolean killFlag) {
		this.killFlag = killFlag;
	}

	@Override
	protected void finalize() throws Throwable {
		super.finalize();
		System.out.println("DownloadThread finalize");
	}

}
